package devlight.io.sample;


import com.gigamole.arcprogressstackview.ResourceTable;

import com.leaking.slideswitch.SlideSwitch;
import devlight.io.library.ArcProgressStackView;

import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.agp.animation.Animator;
import ohos.agp.components.Button;
import ohos.agp.components.Component;
import ohos.agp.components.Slider;
import ohos.agp.components.StackLayout;
import ohos.agp.utils.Color;
import ohos.agp.utils.LayoutAlignment;
import ohos.agp.window.dialog.ToastDialog;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.global.resource.NotExistException;
import ohos.global.resource.ResourceManager;
import ohos.global.resource.WrongTypeException;

import java.io.IOException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Random;

/**
 * 主界面
 */
public class MainActivity extends Ability implements Component.ClickedListener, Slider.ValueChangedListener, SlideSwitch.SlideListener {
    public static final int MODEL_COUNT = 4;

    // APSV
    private ArcProgressStackView mArcProgressStackView;

    // Buttons
    private Button mBtnShadowColor;
    private Button mBtnTextColor;

    // Wrappers
    private Component mWrapperShadow;
    private Component mWrapperAnimation;

    // Parsed colors
    private int[] mStartColors = new int[MODEL_COUNT];
    private int[] mEndColors = new int[MODEL_COUNT];

    // First full size of APSV
    private int mFullSize = -1;
    private int screenWidth;
    private int screenHeight;

    @Override
    protected void onStart(Intent intent) {
        super.onStart(intent);
        setUIContent(ResourceTable.Layout_activity_main);
        init();
    }

    /**
     * 初始化
     */
    public void init() {
        // Get APSV
        mArcProgressStackView = (ArcProgressStackView) findComponentById(ResourceTable.Id_apsv);
        // Get colors
        ResourceManager resourceManager = getResourceManager();
        String[] bgColors = new String[4];
        try {
            String[] startColors = resourceManager.getElement(ResourceTable.Strarray_devlight).getStringArray();
            String[] endColors = resourceManager.getElement(ResourceTable.Strarray_default_preview).getStringArray();
            bgColors = resourceManager.getElement(ResourceTable.Strarray_medical_express).getStringArray();
            for (int i = 0; i < MODEL_COUNT; i++) {
                mStartColors[i] = Color.getIntColor(startColors[i]);
                mEndColors[i] = Color.getIntColor(endColors[i]);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NotExistException e) {
            e.printStackTrace();
        } catch (WrongTypeException e) {
            e.printStackTrace();
        }
        // Set models
        final ArrayList<ArcProgressStackView.Model> models = new ArrayList<>();
        models.add(new ArcProgressStackView.Model("Strategy", 0, new Color(Color.getIntColor(bgColors[0])), new Color(mStartColors[0])));
        models.add(new ArcProgressStackView.Model("Design", 0, new Color(Color.getIntColor(bgColors[1])), new Color(mStartColors[1])));
        models.add(new ArcProgressStackView.Model("Development", 0, new Color(Color.getIntColor(bgColors[2])), new Color(mStartColors[2])));
        models.add(new ArcProgressStackView.Model("QA", 0, new Color(Color.getIntColor(bgColors[3])), new Color(mStartColors[3])));
        mArcProgressStackView.setModels(models);

        // Get wrappers
        mWrapperShadow = findComponentById(ResourceTable.Id_wrapper_shadow);
        mWrapperAnimation = findComponentById(ResourceTable.Id_wrapper_animation);

        // Get checkboxes
        final SlideSwitch cbAnimating = (SlideSwitch) findComponentById(ResourceTable.Id_cb_animating);
        final SlideSwitch cbDragging = (SlideSwitch) findComponentById(ResourceTable.Id_cb_dragging);
        final SlideSwitch cbShadowing = (SlideSwitch) findComponentById(ResourceTable.Id_cb_shadowing);
        final SlideSwitch cbRounding = (SlideSwitch) findComponentById(ResourceTable.Id_cb_rounding);
        final SlideSwitch cbLeveling = (SlideSwitch) findComponentById(ResourceTable.Id_cb_leveling);
        final SlideSwitch cbShowModelBg = (SlideSwitch) findComponentById(ResourceTable.Id_cb_show_model_bg);
        final SlideSwitch cbUseCustomTypeface = (SlideSwitch) findComponentById(ResourceTable.Id_cb_use_custom_typeface);
        final SlideSwitch cbUseOvershootInterpolator = (SlideSwitch) findComponentById(ResourceTable.Id_cb_use_overshoot_interpolator);
        final SlideSwitch cbUseVerticalOrientation = (SlideSwitch) findComponentById(ResourceTable.Id_cb_use_vertical_orientation);
        final SlideSwitch cbUseGradient = (SlideSwitch) findComponentById(ResourceTable.Id_cb_use_gradient);

        // Set checkboxes
        cbAnimating.setSlideListener(this);
        cbDragging.setSlideListener(this);
        cbShadowing.setSlideListener(this);
        cbRounding.setSlideListener(this);
        cbShowModelBg.setSlideListener(this);
        cbLeveling.setSlideListener(this);
        cbUseCustomTypeface.setSlideListener(this);
        cbUseOvershootInterpolator.setSlideListener(this);
        cbUseVerticalOrientation.setSlideListener(this);
        cbUseGradient.setSlideListener(this);

        cbAnimating.setState(true);
        cbShadowing.setState(false);
        cbDragging.setState(true);
        cbUseCustomTypeface.setState(true);
        cbShowModelBg.setState(true);

        // Get buttons
        mBtnTextColor = (Button) findComponentById(ResourceTable.Id_btn_text_color);
        mBtnShadowColor = (Button) findComponentById(ResourceTable.Id_btn_shadow_color);
        final Button btnAnimate = (Button) findComponentById(ResourceTable.Id_btn_animate);
        final Button btnPresentation = (Button) findComponentById(ResourceTable.Id_btn_presentation);
        final Button btnReset = (Button) findComponentById(ResourceTable.Id_btn_reset);

        // Set buttons
        mBtnTextColor.setClickedListener(this);
        mBtnShadowColor.setClickedListener(this);
        btnAnimate.setClickedListener(this);
        btnPresentation.setClickedListener(this);
        btnReset.setClickedListener(this);

        // Set default colors
        handleSelectedColor(true, Color.DKGRAY);
        handleSelectedColor(false, Color.WHITE);

        // Get seekers
        final Slider sbViewSize = (Slider) findComponentById(ResourceTable.Id_pb_view_size);
        final Slider sbShadowDistance = (Slider) findComponentById(ResourceTable.Id_pb_shadow_distance);
        final Slider sbShadowAngle = (Slider) findComponentById(ResourceTable.Id_pb_shadow_angle);
        final Slider sbShadowRadius = (Slider) findComponentById(ResourceTable.Id_pb_shadow_radius);
        final Slider sbAnimationDuration = (Slider) findComponentById(ResourceTable.Id_pb_animation_duration);
        final Slider sbDrawWidth = (Slider) findComponentById(ResourceTable.Id_pb_draw_width);
        final Slider sbModelOffset = (Slider) findComponentById(ResourceTable.Id_pb_model_offset);
        final Slider sbStartAngle = (Slider) findComponentById(ResourceTable.Id_pb_start_angle);
        final Slider sbSweepAngle = (Slider) findComponentById(ResourceTable.Id_pb_sweep_angle);

        // Set seekers
        sbViewSize.setValueChangedListener(this);
        sbShadowDistance.setValueChangedListener(this);
        sbShadowAngle.setValueChangedListener(this);
        sbShadowRadius.setValueChangedListener(this);
        sbAnimationDuration.setValueChangedListener(this);
        sbDrawWidth.setValueChangedListener(this);
        sbModelOffset.setValueChangedListener(this);
        sbStartAngle.setValueChangedListener(this);
        sbSweepAngle.setValueChangedListener(this);

        // Set animator listener
        mArcProgressStackView.setAnimatorListener(new Animator.StateChangedListener() {
            @Override
            public void onStart(Animator animator) {
            }

            @Override
            public void onStop(Animator animator) {
            }

            @Override
            public void onCancel(Animator animator) {
            }

            @Override
            public void onEnd(Animator animator) {
                ToastDialog toastDialog = new ToastDialog(MainActivity.this);
                toastDialog.setText("ANIMATION");
                toastDialog.setDuration(1000);
                toastDialog.setAlignment(LayoutAlignment.CENTER);
                toastDialog.show();
            }

            @Override
            public void onPause(Animator animator) {
            }

            @Override
            public void onResume(Animator animator) {
            }
        });

        // Start apsv animation on start
        new EventHandler(EventRunner.getMainEventRunner()).postTask(new Runnable() {
            @Override
            public void run() {
                btnAnimate.callOnClick();
            }
        }, 333);

        screenWidth = getResourceManager().getDeviceCapability().width
                * getResourceManager().getDeviceCapability().screenDensity / 160;
        screenHeight = getResourceManager().getDeviceCapability().height
                * getResourceManager().getDeviceCapability().screenDensity / 160;
    }


    private void onCheckedChanged(int id, boolean isChecked) {
        switch (id) {
            case ResourceTable.Id_cb_animating:
                mArcProgressStackView.setIsAnimated(isChecked);
                mWrapperAnimation.setVisibility(isChecked ? Component.VISIBLE : Component.HIDE);
                break;
            case ResourceTable.Id_cb_dragging:
                mArcProgressStackView.setIsDragged(isChecked);
                break;
            case ResourceTable.Id_cb_shadowing:
                mArcProgressStackView.setIsShadowed(isChecked);
                mWrapperShadow.setVisibility(isChecked ? Component.VISIBLE : Component.HIDE);
                break;
            case ResourceTable.Id_cb_rounding:
                mArcProgressStackView.setIsRounded(isChecked);
                break;
            case ResourceTable.Id_cb_leveling:
                mArcProgressStackView.setIsLeveled(isChecked);
                break;
            case ResourceTable.Id_cb_show_model_bg:
                mArcProgressStackView.setModelBgEnabled(isChecked);
                break;
            case ResourceTable.Id_cb_use_custom_typeface:
                mArcProgressStackView.setTypeface(isChecked ? "agency.ttf" : "");
                break;
            case ResourceTable.Id_cb_use_overshoot_interpolator:
                mArcProgressStackView.setInterpolator(isChecked ? Animator.CurveType.OVERSHOOT : -1);
                break;
            case ResourceTable.Id_cb_use_vertical_orientation:
                mArcProgressStackView.setIndicatorOrientation(isChecked ?
                        ArcProgressStackView.IndicatorOrientation.VERTICAL :
                        ArcProgressStackView.IndicatorOrientation.HORIZONTAL
                );
                break;
            case ResourceTable.Id_cb_use_gradient:
                for (int i = 0; i < mArcProgressStackView.getModels().size(); i++) {
                    final ArcProgressStackView.Model model = mArcProgressStackView.getModels().get(i);
                    model.setColor(new Color(mStartColors[i]));
                    model.setColors(isChecked ? new Color[]{new Color(mStartColors[i]), new Color(mEndColors[i])} : null);
                }
                mArcProgressStackView.postLayout();
                mArcProgressStackView.invalidate();
                break;
            default:
                break;
        }
    }


    private void showColorPicker(final boolean isShadowColor) {
        ColorDialog dialog = new ColorDialog(this, mArcProgressStackView);
        dialog.setSize(screenWidth, screenHeight / 3);
        dialog.setAlignment(LayoutAlignment.CENTER);
        dialog.setConfirmListener(new ColorDialog.ConfirmListener() {
            @Override
            public void onConfirm(Color color) {
                if (isShadowColor) {
                    mArcProgressStackView.setShadowColor(color);
                    mBtnShadowColor.setTextColor(color);
                } else {
                    mArcProgressStackView.setTextColor(color);
                    mBtnTextColor.setTextColor(color);
                }
                dialog.hide();
            }
        });
        dialog.show();
    }

    private void handleSelectedColor(final boolean isShadowColor, final Color selectedColor) {
        if (isShadowColor) {
            mArcProgressStackView.setShadowColor(selectedColor);
            mBtnShadowColor.setTextColor(selectedColor);
        } else {
            mArcProgressStackView.setTextColor(selectedColor);
            mBtnTextColor.setTextColor(selectedColor);
        }
    }

    @Override
    public void onClick(Component component) {
        switch (component.getId()) {
            case ResourceTable.Id_btn_text_color:
                showColorPicker(false);
                break;
            case ResourceTable.Id_btn_shadow_color:
                showColorPicker(true);
                break;
            case ResourceTable.Id_btn_animate:
                final SecureRandom random = new SecureRandom();
                for (ArcProgressStackView.Model model : mArcProgressStackView.getModels()) {
                    model.setProgress(random.nextInt(101));
                }
                mArcProgressStackView.animateProgress();
                break;
            case ResourceTable.Id_btn_reset:
                startAbility(getIntent());
                terminateAbility();
                break;
            case ResourceTable.Id_btn_presentation:
                Intent intent = new Intent();
                Operation operation = new Intent.OperationBuilder()
                        .withBundleName(getBundleName())
                        .withAbilityName(PresentationActivity.class.getCanonicalName())
                        .build();
                intent.setOperation(operation);
                startAbility(intent);
                break;
            default:
                break;
        }
    }


    @Override
    protected void onInactive() {
        super.onInactive();
    }

    @Override
    public void onProgressUpdated(Slider slider, int progress, boolean b) {
        switch (slider.getId()) {
            case ResourceTable.Id_pb_view_size:
                if (mFullSize == -1) {
                    mFullSize = mArcProgressStackView.getSize();
                }
                StackLayout.LayoutConfig layoutConfig = new StackLayout.LayoutConfig(mArcProgressStackView.getLayoutConfig());
                layoutConfig.height = (int) ((mFullSize * 0.5f) +
                        (int) ((float) mFullSize * 0.5f * ((float) progress / 100.0f)));
                layoutConfig.width = layoutConfig.height;
                layoutConfig.alignment = LayoutAlignment.HORIZONTAL_CENTER;
                mArcProgressStackView.setLayoutConfig(layoutConfig);
                mArcProgressStackView.invalidate();
                break;
            case ResourceTable.Id_pb_shadow_distance:
                mArcProgressStackView.setShadowDistance(progress);
                break;
            case ResourceTable.Id_pb_shadow_angle:
                mArcProgressStackView.setShadowAngle(progress);
                break;
            case ResourceTable.Id_pb_shadow_radius:
                mArcProgressStackView.setShadowRadius(progress);
                break;
            case ResourceTable.Id_pb_animation_duration:
                mArcProgressStackView.setAnimationDuration(progress);
                break;
            case ResourceTable.Id_pb_draw_width:
                mArcProgressStackView.setDrawWidthFraction((float) progress / 100.0f);
                break;
            case ResourceTable.Id_pb_model_offset:
                mArcProgressStackView.setProgressModelOffset(progress - 50);
                break;
            case ResourceTable.Id_pb_start_angle:
                mArcProgressStackView.setStartAngle(progress);
                break;
            case ResourceTable.Id_pb_sweep_angle:
                mArcProgressStackView.setSweepAngle(progress);
                break;
            default:
                break;
        }
    }

    @Override
    public void onTouchStart(Slider slider) {
    }

    @Override
    public void onTouchEnd(Slider slider) {
    }


    @Override
    public void open(SlideSwitch slideSwitch) {
        onCheckedChanged(slideSwitch.getId(), true);
    }

    @Override
    public void close(SlideSwitch slideSwitch) {
        onCheckedChanged(slideSwitch.getId(), false);
    }
}
